package io.renren.modules.iots.test.socket.client;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName: SingleSocketClientThread
 * @Description: 单例模式SocketClientThread类
 * @author 周西栋
 * @date 2018年5月8日
 *
 */
public class SingleSocketClientThread implements Runnable {
	
/************************************************      全局变量     ************************************************/
	
    /**
     * 监听器管理器
     * 如果缓冲区有数据，通知程序接收
     */
    public static Set<Selector> selectorSet = new HashSet<>();
    
    /**
     * SocketChannel管理器
     */
    public static Map<SelectionKey,SocketChannel> socketChannelMap = new HashMap<>();
    
    /**
     *  定义重试次数
     */
    private static int trytimes = 100;
    
    /**
     *  服务器是否已经链接
     */
    private static boolean connectstatus = false;
    
    /**
     *  服务器的ip
     */
    private static String serverIP = null;
    
    /**
     *  服务器的端口号
     */
    private static int serverPORT = 0;
    
    /**
     *  客户端的ip
     */
    private static String clientIP = null;
    
    /**
     *  客户端的端口号
     */
    private static int clientPORT = 0;
    
	
	/************************************************      全局变量     ************************************************/
	
	/************************************************      单例模式     ************************************************/
	
    /**
     * 创建一个新的实例 SingleSocketClientThread.
     */
    private SingleSocketClientThread() {
    	new Thread(this).start();
    }
    
    /**
     * 私有对象变量
     */
    private static final SingleSocketClientThread single = new SingleSocketClientThread();
    
    /**
     * @Title: getInstance
     * @Description: 饿汉模式--单例（静态工厂方法） 
     * @param @return    参数
     * @return SingleSocketClientThread    返回类型
     * @throws
     */
    public static SingleSocketClientThread getInstance() {
        return single;
    }
	
	/************************************************      单例模式     ************************************************/
	
    /************************************************      业务处理     ************************************************/
    
    /**
     * @Title: put
     * @Description: 将selector添加到管理器中
     * @param @param selector    参数
     * @return void    返回类型
     * @throws
     */
    public void put(Selector selector){
    	selectorSet.add(selector);
    }
    
    /************************************************      业务处理     ************************************************/
	
	
	
	
	@Override
	public void run() {
		System.out.println("我启动了一个读信息的线程");
        try {
            // 轮询访问selector
            while (true) {
            	for(Selector selector:selectorSet){
            		System.out.println("------------------------------");
            		selector.select();//如果队列有新的Channel加入，那么Selector.select()会被唤醒
                    // 获得selector中选中的项的迭代器
                    Iterator ite = selector.selectedKeys().iterator();
                    System.out.println("selector中选中的项的迭代器长度是："+selector.selectedKeys().size());
                    
                    while (ite.hasNext()) {
                    	System.err.println("走");
                        SelectionKey key = (SelectionKey) ite.next();
                        // 删除已选的key,以防重复处理
                        ite.remove();
                     // 连接事件发生
                        if (key.isConnectable()) {
                        	System.err.println("走1");
                            SocketChannel channel = (SocketChannel) key.channel();
                            // 如果正在连接，则完成连接
                            if (channel.isConnectionPending()) {
                            	System.err.println("走2");
                                channel.finishConnect();
                            }
                            // 将SocketChannel放到管理器中管理
                            SingleSocketReadThread.getInstance().socketChannelMap.put(key, channel);
                            System.err.println("走3");
                            // 设置成非阻塞
                            channel.configureBlocking(false);
                            // 为客户端ip和port赋值
                            clientIP = channel.socket().getInetAddress().getHostAddress();
                            clientPORT = channel.socket().getPort();
                            //在这里可以给服务端发送信息哦
                            channel.write(ByteBuffer.wrap(new String("我们测试中国ab").getBytes()));
                            //在和服务端连接成功之后，为了可以接收到服务端的信息，需要给通道设置读的权限。
                            channel.register(selector, SelectionKey.OP_READ );
                        }
                    }
            	}
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

		
		
		
//		InetSocketAddress addr = new InetSocketAddress (host, port);  
//		SocketChannel sc = SocketChannel.open();  
//		sc.configureBlocking(false);  
//		sc.connect(addr);  
//		while ( ! sc.finishConnect( )) {  
////		    doSomethingElse();  
//		}  
////		doSomethingWithChannel(sc);  
//		sc.close();
		
	}
}